#pragma once
#include <osg/Group>
#include "OCamera.h"
#include "Entity.h"

/**
 * @note Entity is a child of Transform
 * @note Camera is a subclass of Transform
 */
class OGroup : public osg::Group {
public:
	OGroup() {
		// global root node states' setting( may no need manage it by self, OSG auto )
		//StateSet::setDepthTestAndWrite(s_root, true, true);
		//StateSet::setCullingFace(s_root, true);
	}

	~OGroup() { std::cout << ">>> ~OGroup" << std::endl; }

	bool addEntity(Entity* entity) { return addChild(entity); }

	bool removeEntity(Entity* entity) { return removeChild(entity); }

	void clear() { removeChildren(0, getNumChildren()); }

	CVector<Entity*> entities(bool RTT = false) {
		CVector<Entity*> entities;
		osg::Group* root = this;
		if (RTT) {
			root = m_subgraphCameraNode;
			if (!root)
				return entities;
		}
		for (int i = 0; i < root->getNumChildren(); i++) {
			auto entity = dynamic_cast<Entity*>(root->getChild(i));
			if (entity)
				entities << entity;
		}
		return entities;
	}

	bool hasSubgraphCamera() const { return m_subgraphCameraNode != nullptr; }

	void createSubgraphCamera(osg::Camera* viewerIniCamera) {
		if (m_subgraphCameraNode) {
			LogW << "Subgraph camera already exists, cannot add another one." << std::endl;
			return;
		}
		m_subgraphCameraNode = new OCamera;
		addChild(m_subgraphCameraNode);
	}

	void addToSubgraphCamera(Entity* entity) {
		if (!m_subgraphCameraNode) {
			LogW << "Subgraph camera does not exist, cannot add entity to it." << std::endl;
			return;
		}
		m_subgraphCameraNode->addChild(entity);
	}

	void removeFromSubgraphCamera(Entity* entity) {
		if (!m_subgraphCameraNode) {
			LogW << "Subgraph camera does not exist, cannot remove entity from it." << std::endl;
			return;
		}
		m_subgraphCameraNode->removeChild(entity);
	}

	void destroySubgraphCamera() {
		removeChild(m_subgraphCameraNode);
		m_subgraphCameraNode = nullptr;
	}

private:
	OCamera* m_subgraphCameraNode = nullptr;
};